/*
 * 平台相关代码
 *
 * author: lishutong
 * site: https://lishutong1024.cn / https://lishutong1024.github.cn
 */
#ifndef OS_PLAT_H
#define OS_PLAT_H

#include <stdint.h>

typedef uint32_t os_int_status_t;           // 中断状态码
typedef uint32_t cpu_stack_t;               // 栈类型
typedef uint64_t os_ticks_t;                // 时钟节拍计数

// 任务状态：寄存器堆
typedef struct _os_task_ctx_t {
    cpu_stack_t r4;
    cpu_stack_t r5;
    cpu_stack_t r6;
    cpu_stack_t r7;
    cpu_stack_t r8;
    cpu_stack_t r9;
    cpu_stack_t r10;
    cpu_stack_t r11;
    cpu_stack_t r13;

    // 一些标志位
    uint32_t flags;
}os_task_ctx_t;

typedef struct _os_stack_base_frame_t {
    cpu_stack_t r0;
    cpu_stack_t r1;
    cpu_stack_t r2;
    cpu_stack_t r3;
    cpu_stack_t r12;
    cpu_stack_t r14_lr;
    cpu_stack_t pr15_pc;
    cpu_stack_t xpsr;
}os_stack_base_frame_t;

typedef struct _os_stack_base_vfp_t {
    // 使用FPU时，手动压栈部分
    cpu_stack_t s16;
    cpu_stack_t s17;
    cpu_stack_t s18;
    cpu_stack_t s19;
    cpu_stack_t s20;
    cpu_stack_t s21;
    cpu_stack_t s22;
    cpu_stack_t s23;
    cpu_stack_t s24;
    cpu_stack_t s25;
    cpu_stack_t s26;
    cpu_stack_t s27;
    cpu_stack_t s28;
    cpu_stack_t s29;
    cpu_stack_t s30;
    cpu_stack_t s31;
    
    // 总是压栈的部分
    cpu_stack_t r0;
    cpu_stack_t r1;
    cpu_stack_t r2;
    cpu_stack_t r3;
    cpu_stack_t r12;
    cpu_stack_t r14_lr;
    cpu_stack_t pr15_pc;
    cpu_stack_t xpsr;

    // 使用FPU，异常发生时自动压栈
    cpu_stack_t S0;
    cpu_stack_t S1;
    cpu_stack_t S2;
    cpu_stack_t S3;
    cpu_stack_t S4;
    cpu_stack_t S5;
    cpu_stack_t S6;
    cpu_stack_t S7;
    cpu_stack_t S8;
    cpu_stack_t S9;
    cpu_stack_t S10;
    cpu_stack_t S11;
    cpu_stack_t S12;
    cpu_stack_t S13;
    cpu_stack_t S14;
    cpu_stack_t S15;
    cpu_stack_t FPSCR;
    cpu_stack_t noname;
}os_stack_frame_t;

struct _os_task_t;

void os_task_ctx_init(struct _os_task_t *task, void * stack_start, int stack_size, void (*entry)(void *), void * param);

void os_plat_init(void);
os_int_status_t os_plat_int_disable (void);
void os_plat_int_restore (os_int_status_t status);

void os_plat_putc (char c);
void os_plat_ticks_update(os_ticks_t * ticks, int method);

#endif
